/*
 * ScrollerView.java
 * classes : com.slide.ScrollerView
 * @author 梁天刚
 * V 1.0.0
 * Create at 2011-8-23 上午10:46:21
 */
package com.wzz.common.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.PointF;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.FrameLayout;
import android.widget.Scroller;

/**
 * com.slide.ScrollerView
 * 
 * @author 梁天刚 <br/>
 *         create at 2011-8-23 上午10:46:21
 */
public class HorScrollView extends FrameLayout {
  private boolean log = false;
  private Scroller scroller;
  private String TAG;
  private Drawable drawable;

  public HorScrollView(Context context) {
    super(context);
    initialise();
  }

  public HorScrollView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    initialise();
  }

  public HorScrollView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initialise();
  }

  private void initialise() {
    scroller = new Scroller(getContext());
    TAG = getClass().getSimpleName();
  }

  private PointF last = new PointF();
  private final int TOUCH_SLOP = ViewConfiguration.get(getContext()).getScaledTouchSlop();

  @Override
  public boolean onInterceptTouchEvent(MotionEvent event) {
    final float x = event.getX();
    final int action = event.getAction();
    boolean flag = false;

    if (action == MotionEvent.ACTION_DOWN) {
      last.x = x;
    } else if (action == MotionEvent.ACTION_MOVE) {
      flag = Math.abs(last.x - x) > TOUCH_SLOP;
    }
    return flag;
  }

  public boolean onTouchEvent(MotionEvent event) {
    super.onTouchEvent(event);
    final int x = (int) event.getX();
    final int width = getWidth();

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
      d("onTouchEvent ACTION_DOWN");
      if (!scroller.isFinished()) {
        scroller.abortAnimation();
      }

      break;
    case MotionEvent.ACTION_MOVE:
      d("onTouchEvent ACTION_MOVE");
      final int deltaX = (int) (last.x - x);
      if (Math.abs(deltaX) < TOUCH_SLOP) {
        break;
      }
      last.x = x;
      if (deltaX < 0) {
        if (getScrollX() > 0) {
          scrollBy(Math.max(-getScrollX(), deltaX), 0);
        }
      } else if (deltaX > 0) {
        final int availableToScroll = getChildAt(getChildCount() - 1).getRight() - getScrollX() - getWidth();
        if (availableToScroll > 0) {
          scrollBy(Math.min(availableToScroll, deltaX), 0);
        }
      }

      break;
    case MotionEvent.ACTION_UP:
    case MotionEvent.ACTION_CANCEL:
      d("onTouchEvent ACTION_UP || ACTION_CANCEL");
      int dx = (getScrollX() + width / 2) / width;
      if (dx < 0) {
        dx = 0;
      }
      if (dx > getChildCount() - 1) {
        dx = getChildCount() - 1;
      }
      dx *= width;
      dx -= getScrollX();
      scroller.startScroll(getScrollX(), 0, dx, 0, Math.abs(dx) * 3);
      break;
    }
    invalidate();
    return true;
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    final int width = getWidth();
    final int count = getChildCount();
    int height = getHeight();
    int childLeft = 0;
    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      child.layout(childLeft, 0, childLeft + width, height);
      childLeft += width;
    }
  }

  @Override
  public void setBackgroundDrawable(Drawable d) {
    drawable = d;
    super.setBackgroundDrawable(null);
  }

  @Override
  protected void dispatchDraw(Canvas canvas) {
    int childCount = getChildCount();
    if (null != drawable) {
      drawable.setBounds(0, 0, childCount == 0 ? getWidth() : childCount * getWidth(), getHeight());
      drawable.draw(canvas);
    }
    super.dispatchDraw(canvas);
  }

  @Override
  public void computeScroll() {
    if (scroller.computeScrollOffset()) {
      scrollTo(scroller.getCurrX(), scroller.getCurrY());
      invalidate();
    }
  }

  public int getCurrentIndex() {
    int width = getMeasuredWidth();
    return width == 0 ? -1 : (getScrollX() + width / 2) / width;
  }

  @Override
  public void removeAllViews() {
    super.removeAllViews();
    requestLayout();
    scrollTo(0, 0);
  }

  @Override
  public void removeView(View view) {
    super.removeView(view);
    requestLayout();
  }

  @Override
  public void removeViewAt(int index) {
    super.removeViewAt(index);
    requestLayout();
  }

  /**
   * 直接显示第which页
   * 
   * @param which
   */
  public void directShow(int which) {
    which = Math.min(Math.max(which, 0), getChildCount() - 1);
    if (getMeasuredWidth() == 0 || which == getCurrentIndex() || getChildCount() == 0) {
      return;
    }
    scrollTo(which * getWidth(), 0);
    invalidate();
  }
  
  void d(String message){
    if(log){
      Log.d(TAG, message);
    }
  }
}